unit stl_base;
{$O+}
interface
uses Stl_types;
type Pbasetype = ^Basetype;
  Basetype=record
    data: StlType;
    id: Longint;
    next, prev: Pbasetype;
  end;
type iterator = Pbasetype;
Type Pbase = ^Iterator;
type Container = class
private
  //data: packed array of PBaseType;
  //data:Pbase;
  r_size: Cardinal;
  _IBegin, _Iend: Iterator;
  rsorted: boolean;
  procedure realloc;
  procedure size_Recalc;
  procedure wrtSorted(const Value: boolean);

public
  size: int64;
  constructor Create; overload;
 // constructor Create(const size_t: longint); overload;
  function Empty: boolean;
  function get(const i:longint):StlType;overload;
  function get(const it: Iterator):StlType;overload;
  function find(const elem: STLTYPE): iterator; overload;
  function find(const it: iterator): boolean; overload;
  procedure Clear;
  procedure insert(const elem: StlType; const i:longint); overload;
  procedure insert(const elem: StlType; const position:Iterator); overload;
  procedure reserve(const size_t: longint);
  procedure Delete(const elem: StlType);overload;
  procedure Delete(const It:Iterator);overload;
  procedure reverse;
  function _Begin: Iterator;
  function _END: Iterator;
published
 // property sorted Read rsorted Write WrtSorted;
 // property _Begin:Iterator Read _IBEGIN^;
 // property _END:Iterator Read _IEND^;
end;

implementation
{$IFDEF WIN32}
uses
  Windows, SysUtils, Stlmain;
{$ELSE}
uses
  SysUtils, Stlmain;
{$ENDIF}
constructor Container.Create;
var
  _pbegin, _pend : Iterator;
begin
    inherited Create;
    new(_IBEGIN);
    new(_IEND);
    _Ibegin^.prev := _Iend;
    _Ibegin^.next := _Iend;
    _Iend^.next := _Ibegin;
    _Iend^.prev := _Ibegin;
    r_size := 0;
    size := 0;
    {$IFDEF DEBUG}
       // fillchar(data, sizeof(a), 0);
    {$ENDIF}
end;
procedure Container.WrtSorted(const Value:boolean);
begin
  rsorted := value;
end;
{constructor Container.Create(const size_t: longint); 
begin
    inherited Create;
    size := size_t;
    _IBEGIN := nil;
    _IEND := nil;
    
end;}

function container.find(const it: Iterator): boolean;
var
  _cur: Iterator;
  res: boolean;
begin
  res := false;
  if Empty then exit;
  _cur := _IBegin;
  while (_cur <> _IEND)and(_cur <> it) do
    _cur :=  _cur^.next;
  find := (_cur <> _IEND);
end;

procedure Container.clear;
begin
    {_Ibegin := nil;
    _Iend := nil;   }
    _Ibegin^.prev := _Iend;
    _Ibegin.data := _none;
    _Ibegin^.next := _Iend;
    _Iend^.next := _Ibegin;
    _Iend.data := _none;
    _Iend^.prev := _Ibegin;
    r_size := 0;
    size := 0;
end;

function Container.empty: boolean;
begin
    empty := (_IBEGIN^.next = _IEND)and(_IEND^.prev=_IBEGIN);
end;

function Container._END:Iterator;
begin
  _END := _IEND;
end;

function Container._BEGIN:Iterator;
begin
  _Begin := _Ibegin;
end;

procedure container.size_Recalc;
var
  it: Iterator;
  cnt: int64;
begin
  it := _Ibegin;
  cnt := 0;
  while (it <> nil) do
  begin
    inc(cnt);
    it := it^.next;
  end;
  size := cnt;
end;

procedure Container.insert(const elem: StlType; const position: Iterator);  
begin
    if (position = nil)then
      exit;
    position^.data := elem;
end;

procedure Container.insert(const elem: StlType; const i: Longint);
var
  cnt: Longint;
  it:Iterator;
  p: Iterator;
begin
  rsorted :=false;
  if (abs(i - size) > 1) then exit;
  if (i <= 0) then exit;
  if (Empty) then
  begin
    New(P);
    inc(size);
    P^.data := elem;
    _Ibegin^.next := P;
    P^.next := _IEND;
    P^.prev := _IBEGIN;
    _IEND^.prev := P;
    exit;
  end;
  cnt := 0;
  it := _IBEGIN;
  while (cnt < i)and(it <> _IEND) do
  begin
    inc(cnt);
    it := it^.next;
  end;
  if (it = _IEND) then  //insert in end
  begin
    new(P);
    inc(size);
    P^.data := elem;
    P^.next := _IEND;
    P^.prev := _IEND^.prev;
    _IEND^.prev^.next := P;
    _IEND^.prev := P;
  end
  else
    begin
      It^.data := elem;
    end;
end;

procedure Container.reserve(const size_t: longint);
begin
    {if (size_t > r_size) then
    begin
        SetLength(data, size_t);
        r_size := size_t;
    end;  }
end;

procedure Container.realloc;
begin
   { if (size > r_size) then
    begin
        SetLength(data, r_size * 2);
        r_size := r_size * 2;
    end;  }
end;


procedure Container.reverse;
var
  _l, _R: Iterator;
begin
  rsorted := false;
  _L := _Ibegin.next;
  _R := _IEND.prev;
  while ((_L^.prev <> _R)or(_R.next <> _L))and(_L <> _R) do
  begin
    swp(_L^.data, _R^.data);
    _L := _L^.next;
    _R := _R^.prev;
  end;
end;

function Container.Find(const elem: StlType):iterator;
var
  it: Iterator;
begin
  if (Empty) then exit;
  it := _IBEGIN;
  while (It <> _IEND) and(not Equal(it^.data, elem))  do
    it := it^.next;
  if (it = _IEND) then
    find := nil
  else
    find := it;
end;

function Container.get(const i:Longint): StlType;
var
  cnt: longint;
  it: Iterator;
begin
  get := _none;
  if (Empty) then exit;
  it := _IBEGIN;
  cnt := 0;
  if (i <=0) then exit;
  while (cnt < i) and (it <> _IEND) do
  begin
    it := It^.next;
    inc(cnt);
  end;
  if (cnt = i) then
    get := it^.data
  else
    get := _None;
end;

function Container.get(const it:Iterator):StlType;
begin
  if (it <> nil) then
    get := it^.data
  else
    get := _None;
end;

procedure container.Delete(const elem:StlType);
var
  it: iterator;
begin
  rsorted := false;
  it := Find(elem);
  if (it = nil) then exit;
  Delete(it);
  //Dispose(it);
end;

procedure container.Delete(const it:iterator);
begin
  rsorted := false;
  it^.prev^.next := it^.next;
  it^.next^.prev := it^.prev;
  size_Recalc;
  Dispose(it);
end;

end.
